/*  Universidad del Valle de Guatemala
 *  Algoritmos y Estructura de datos
 * 
 * Rodimiro Castañeda, 12122
 * Carlos Sagastume, 12113
 * 
 * Descripcion:
 *      programa que utiliza un patron de diseño para seleccionar la implementacion de SET que se
 * usara, en tiempo de corrida. Entre las opciones de implementacion de SET se encuentra: HashSet, TreeSet 
 * y LinkedHashSet. El programa forma tres conjuntos: Java, Web y Celulares, los cuales representan la 
 * lista de personas que son desarrolladores en esas plataformas. Luego se realizan algunas operaciones de
 * conjuntos con el proposito de determinar que desarrolladores estan en determinadas listas.
 * El programa muestra los resultados a las siguientes preguntas:
 * 1. Desarrolladores con experiencia en Java, web y celulares. (Es decir la intersección de los tres conjuntos).
 * 2. Desarrolladores con experiencia en Java pero que no tengan experiencia en web.
 * 3. Desarrolladores con experiencia en Web y Celulares (intersección de Web y Celuares), pero que no tengan experiencia
 * en java.
 * 4. Desarrolladores con experiencia en Web o Celulares (unión de Web y Celuares), pero que no tengan experiencia en java.
 * 5. Indicar SI o NO el conjunto de desarrolladores Java es un subconjunto de Desarrolladores Web.
 * 6. El conjunto (Java, Web o Celulares) que tenga la cantidad más grande de desarrolladores, y los nombres de esos
 * desarrolladores.
 * 7. Del conjunto que tenga la mayor cantidad de desarrolladores, desplegar la lista de los nombres de sus integrantes en
 * orden ascendente.
 * 
 */



//se importa Scanner para el ingreso de datos por parte del usuario
import java.util.*;
public class main {
    public static void main(String [] args)
    {   
        
        //se crea el objeto scaner para elingreso de datos
        Scanner scan = new Scanner(System.in);
        // variable que contendra el numero de la opcion que se dea realizar
        int opc;
        // se crea el objeto factory
        FactorySET seleccion = new FactorySET();
        // variable que contendra texto
        String texto;
        // objeto de ingreso, para que se realizen los ingresos correctos
        Ingreso prueba = new Ingreso();
        // variable booleana para comprobacion de ingreso de texto
        boolean flag;
        // variable que contiene el ingreso de opciones en formato String
        String texto2;
        //se le pide al usuario que ingrese que implementacion desea usar:
        System.out.println("Ingrese el numero de la opcion que desea implementar:\n"
                + "1- HashSet"
                + "\n2- TreeSet"
                + "\n3- LinkedHashSet");
        texto2 = scan.next();
        flag = prueba.Numeros(texto2,1,3);
        while(flag == false){
            System.out.println("Se ha realizado un ingreso incorrecto, ingrese una opcion correcta.");
            texto2 = scan.next();
            flag = prueba.Numeros(texto2,1,3);
        }
        opc = prueba.getnum();
        // se cren los conjuntos de desarrolladores
        Set<String> Java = seleccion.getStack(opc);
        Set<String> Web = seleccion.getStack(opc);
        Set<String> Celulares = seleccion.getStack(opc);
        // listas que contendra los resultados de las operaciones
        Set<String> Lista = seleccion.getStack(opc);
        // resultado de la interseccion
        Set<String> res1 = seleccion.getStack(opc);
        // resultado del inciso 2
        Set<String> res2 = seleccion.getStack(opc);
        // resultado del inciso 3
        Set<String> res3 = seleccion.getStack(opc);
        // resultado del inciso 4
        Set<String> res4 = seleccion.getStack(opc);
        // resultado del inciso 5
        Set<String> res5 = seleccion.getStack(opc);
        // resultado del inciso 6
        Set<String> res6 = seleccion.getStack(opc);
        // resultado del inciso 7
        Set<String> res7 = seleccion.getStack(opc);
        // Ingreso de nombres
        opc = 1;
        do
        {
            System.out.println("Ingrese el nombre del Trabajador: ");
            texto = scan.next();
            System.out.println("Es desarrollador de Java:\n1- SI\n2- No");   
            texto2 = scan.next();
            flag = prueba.Numeros(texto2,1,2);
            while(flag == false){
                System.out.println("Se ha realizado un ingreso incorrecto, ingrese una opcion correcta.");
                texto2 = scan.next();
                flag = prueba.Numeros(texto2,1,2);
            }
            opc = prueba.getnum();
            if (opc == 1)
            {
                Java.add(texto);
            }
            System.out.println("Es desarrollador de Web:\n1- SI\n2- No");
            texto2 = scan.next();
            flag = prueba.Numeros(texto2,1,2);
            while(flag == false){
                System.out.println("Se ha realizado un ingreso incorrecto, ingrese una opcion correcta.");
                texto2 = scan.next();
                flag = prueba.Numeros(texto2,1,2);
            }
            opc = prueba.getnum();
            if (opc == 1)
            {
                Web.add(texto);
            }
            System.out.println("Es desarrollador de Celulares:\n1- SI\n2- No");
            texto2 = scan.next();
            flag = prueba.Numeros(texto2,1,2);
            while(flag == false){
                System.out.println("Se ha realizado un ingreso incorrecto, ingrese una opcion correcta.");
                texto2 = scan.next();
                flag = prueba.Numeros(texto2,1,2);
            }
            opc = prueba.getnum();
            if (opc == 1)
            {
                Celulares.add(texto);
            }
            System.out.println("Desea ingresar otro nombre?\n1- Si\n2- No");
            texto2 = scan.next();
            flag = prueba.Numeros(texto2,1,2);
            while(flag == false){
                System.out.println("Se ha realizado un ingreso incorrecto, ingrese una opcion correcta.");
                texto2 = scan.next();
                flag = prueba.Numeros(texto2,1,2);
            }
            opc = prueba.getnum();
    }
    while(opc == 1);
        
System.out.println("----------------------------------------------\n"
        + "------------------Resultados------------------\n"
        + "----------------------------------------------");
        
        //se realizan las operaciones con la lista
        //1- se realiza la operacion interseccion entre los tres conjuntos (java, web, celulares)
        Lista.addAll(Web);
        Lista.retainAll(Java);
        Lista.retainAll(Celulares);
        res1 = Lista;
        System.out.println("Desarrolladores con experiencia en Java, Web y Celulares: \n"+res1);
        Lista.clear();
        //2- experiencia en java pero que no tengan experiencia en web obtener 
        //interseccion y quitarselo al conjunto de java
        Lista.addAll(Java);
        Lista.removeAll(Web);
        res2 = Lista;
        System.out.println("Trabajadores en Java que no tiene conosimiento de Web: \n"+res2);
        Lista.clear();
        //3- experiencia en WEB y Celulares (interseccion de web y Celulares), pero no tengan experiencia en java
        Lista.addAll(Celulares);
        Lista.retainAll(Web);
        Lista.removeAll(Java);
        res3 = Lista;
        System.out.println("Experiencia en Web y Celulares pero no en Java: \n"+res3);
        Lista.clear();
        //4- Desarrolladores con experiencia en Web o Celulares (union web celulares) pero que no tengran experiencia en java
        Lista.addAll(Web);
        Lista.addAll(Celulares);
        Lista.removeAll(Java);
        res4 = Lista;
        System.out.println("Experiencia en Web o Celulares pero no en Java: \n"+res4);
        //5- indicar si o no el conjunto de desarrolladores java es subconjunto de desarrolladores web
        boolean subconjunto;
        subconjunto = Java.containsAll(Web);
        if (subconjunto == false)
        {
            System.out.println("El conjunto de Java es un subconjunto del conjunto de Web");
        }
        else 
        {
            System.out.println("El conjunto de Java NO es un subconjunto del conjunto Web");
        }
        //6- mostrar el conjunto que tenga mayor cantidad de desarrolladores y los nombres de los desarrolladores
        texto = "";
        if (Web.size() > Java.size())
        {
            if (Web.size() > Celulares.size())
            {
                res6 = Web;
                texto = "Web";
            }
            else
            {
                res6 = Celulares;
                texto = "Celulares";
            }
        }
        else if (Java.size() > Web.size())
        {
            if (Java.size() > Celulares.size())
            {
                res6 = Java;
                texto = "Java";
            }
            else
            {
                res6 = Celulares;
                texto = "Celulares";
            }
        }
        else if (Celulares.size() > Java.size() && Celulares.size() > Web.size())
            {
            res6 = Celulares;
            texto = "Celulares";
            }
        else
        {
            texto = "Existen conjuntos que tienen el mismo numero de elementos.";
        }
        System.out.println("El conjunto con mayor numero de elementos es: "+texto);
        //7- el conjunto que tenga mayor cantidad de desarrolladores, mostrar la lista en orden ascendente
        Set ordenado = new TreeSet(res6);
        System.out.println("Conjunto con mayor cantidad de desarrolladores: "+texto+"\n"+ordenado);
    } 
}
